package com.net.xpay.admin.controller.admin;

import com.google.common.base.Preconditions;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.net.xpay.core.model.*;
import com.net.common.exception.BusinessException;
import com.net.common.model.ResultData;
import com.net.common.model.ResultPagedList;
import com.net.xpay.admin.vo.OpenAppVo;
import com.net.xpay.admin.vo.PublicKeyVo;
import com.net.xpay.common.domain.User;
import com.net.xpay.common.domain.openapi.OpenApp;
import com.net.xpay.common.enums.openapi.OpenAppStatus;
import com.net.xpay.common.manager.UserManager;
import com.net.xpay.common.manager.openapi.OpenAppManager;
import com.net.xpay.common.util.RSA2Util;
import com.net.xpay.core.constant.PoseidonErrorCode;
import com.net.xpay.core.utils.BeanCopierUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

@Slf4j
@RestController
@RequestMapping("/admin/open-app")
@Api(tags = "运营/应用管理", description = "运营 应用管理 ")
public class AdminOpenAppController {

    @Autowired
    private OpenAppManager openAppManager;

    @Autowired
    private UserManager userManager;

    @ApiOperation("搜索")
    @PostMapping("/search")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::search')")
    public ResultPagedList<OpenAppVo> searchOpenApp(@RequestBody OpenAppSearchModel searchModel) {
        List<OpenApp> records = openAppManager.search(searchModel);
        long count = openAppManager.searchCount(searchModel);
        List<OpenAppVo> vos = BeanCopierUtil.batchCopy(OpenApp.class, OpenAppVo.class, records);
        for (OpenAppVo vo : vos) {
            User user = userManager.getById(vo.getUserId());
            vo.setUserName(user.getName());
        }
        return new ResultPagedList<>(vos, count, searchModel);
    }

    @ApiOperation("查看平台公钥")
    @PostMapping("/select-appPublickey")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::select-appPublickey')")
    public ResultData<PublicKeyVo> selectAppPublicKey(@RequestBody IdModel model) {
        Preconditions.checkArgument(model.getId() != null);

        OpenApp openApp = openAppManager.getById(model.getId());
        if (Strings.isNullOrEmpty(openApp.getPublicKey())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "平台公钥暂未生成，请先去生成平台公钥！");
        }
        PublicKeyVo vo = new PublicKeyVo();
        vo.setPublicKey(openApp.getPublicKey());
        return new ResultData<>(vo);
    }

    @ApiOperation("新增")
    @PostMapping("/save")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::save')")
    public ResultData<Boolean> saveOpenApp(@RequestBody SaveOpenAppModel model) throws NoSuchAlgorithmException {
        if (model.getUserId() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "商户id不可为空");
        }
        OpenApp openApp = openAppManager.getByUserId(model.getUserId());
        if (openApp != null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用已存在");
        }
        OpenApp app = new OpenApp();
        app.setUserId(model.getUserId());
        app.setStatus(OpenAppStatus.CLOSED);
        String[] rsa2 = RSA2Util.genRSA2();
        app.setPublicKey(rsa2[0]);
        app.setPrivateKey(rsa2[1]);
        app.setCheckIp(true);
        openAppManager.save(app);
        return new ResultData<>(true);
    }

    @ApiOperation("修改")
    @PostMapping("/update")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::update')")
    public ResultData<Boolean> updateOpenApp(@RequestBody UpdateOpenAppModel model) {
        if (Strings.isNullOrEmpty(model.getAppPublicKey())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用公钥不可为空");
        }
        OpenApp openApp = openAppManager.getById(model.getId());
        if (openApp == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用不存在");
        }
        openApp.setAppPublicKey(model.getAppPublicKey());
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }

    @ApiOperation("应用上线")
    @PostMapping("/open")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::open')")
    public ResultData<Boolean> openOpenApp(@RequestBody IdModel model) {
        if (model.getId() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用id不可为空");
        }
        OpenApp openApp = openAppManager.getById(model.getId());
        if (openApp == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用不存在");
        }
        if (Strings.isNullOrEmpty(openApp.getAppPublicKey())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请先配置应用公钥");
        }
        if (openApp.getCheckIp() && CollectionUtils.isEmpty(openApp.getWhiteIps())) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请先配置ip白名单");
        }
        if(openApp.getStatus().equals(OpenAppStatus.OPEN)){
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用已上线");
        }
        openApp.setStatus(OpenAppStatus.OPEN);
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }

    @ApiOperation("应用下线")
    @PostMapping("/closed")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::closed')")
    public ResultData<Boolean> closedOpenApp(@RequestBody IdModel model) {
        if (model.getId() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用id不可为空");
        }
        OpenApp openApp = openAppManager.getById(model.getId());
        if (openApp == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用不存在");
        }
        if(openApp.getStatus().equals(OpenAppStatus.CLOSED)){
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用状态异常");
        }
        openApp.setStatus(OpenAppStatus.CLOSED);
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }

    @ApiOperation("修改ip白名单")
    @PostMapping("/update-whiteIps")
    @ResponseBody
    @PreAuthorize("hasAnyRole('ADMIN', 'open-app::update-whiteIps')")
    public ResultData<Boolean> updateOpenAppWhiteIps(@RequestBody UpdateWhiteIpsModel model) {
        if (model.getCheckIp() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "请选择是否开启白名单效验");
        }
        if (model.getCheckIp() && model.getWhiteIps() == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "白名单ips不可为空");
        }
        OpenApp openApp = openAppManager.getById(model.getId());
        if (openApp == null) {
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "应用不存在");
        }
        openApp.setCheckIp(model.getCheckIp());
        String whiteIps = model.getWhiteIps();
        List<String> ips = new ArrayList<>();
        if (!Strings.isNullOrEmpty(whiteIps)) {
            whiteIps = whiteIps.trim();
            //中文逗号换成英文逗号
            whiteIps = whiteIps.replace("，", ",");
            ips = Splitter.on(",").omitEmptyStrings().trimResults().splitToList(whiteIps);
        }
        if (ips.size() > 10){
            throw new BusinessException(PoseidonErrorCode.PARAMETER_ILLEGAL, "白名单ips不能超过10个");
        }
        openApp.setWhiteIps(ips);
        openAppManager.update(openApp);
        return new ResultData<>(true);
    }


}
